Skip to content

Allow CSS custom properties to be used without converting to camel case #85

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

kristerkari
Copy link
Contributor

Currently the parser turns any CSS property names to camel case.

There is however a use case for implementing support for CSS Custom properties. Here's an example of how custom props can be used:
kristerkari/react-native-stylus-transformer#3 (comment)

So if we just don't turn the custom property to camel case, everything works like it did before, but implementations of updating custom properties with Javascript are now possible.

ping @jacobp100

@jacobp100
Copy link
Contributor

jacobp100 commented Jun 18, 2018

Is there a reason to handle this in this library? I’m doing the same thing in cssta, but handle the splitting filter variable declarations before handing them off to here (see getStyleDeclarations)

Happy to hear if there’s a reason to do otherwise though!

@kristerkari
Copy link
Contributor Author

Is there a reason to handle this in this library?

What I thought was that it's easy to handle here because the values for the custom props will be handled by the parser, e.g.

--my-prop: 56px;

to

"--my-prop": 56

@kristerkari
Copy link
Contributor Author

kristerkari commented Jun 18, 2018

I could of course handle them in the library level, but then that's just unnecessary boilerplate to: first strip out the --, then give it to the parser that turns the prop to camel case, then take the result and turn the prop back to kebab case and add -- in the beginning.

@jacobp100
Copy link
Contributor

jacobp100 commented Jun 18, 2018

I’m not sure that works. If you did,

--test: 5px;
z-index: var(--test);

This shouldn’t work, but I think in your example it will

@jacobp100 jacobp100 closed this Jun 18, 2018
@jacobp100 jacobp100 reopened this Jun 18, 2018
@kristerkari
Copy link
Contributor Author

kristerkari commented Jun 18, 2018

@jacobp100 I'm not sure what your point is here. I think that I need to explain what I'm trying to achive. :)

What did previously was to allow various CSS units to be passed through the parser:
#83

With that I was able to add support for CSS viewport units, which are calculated at runtime.

What I want now is to pass custom properties (e.g. --my-prop) through the parser without the property name being modified, but convert the value of the custom property to something that React Native can understand. Doing that does not break the current functionality in any way.

The part where the custom property gets used (e.g.var(--my-prop)) is something that this CSS parser does not need to worry about.

So css-to-react-native will handle the parsing of the properties/values, but the support for CSS Custom properties is implemented elsewhere.

For example I want css-to-react-native to parse this:

--my-prop: 4px;
--other-prop: 4vw;
font-size: var(--other-prop);

to this:

{
  "--my-prop": 4,
  "--other-prop": "4vw",
  fontSize: "var(--other-prop)"
}

That code will just give a warning or throw an error in React Native, but if I have a library between the result from this parser and React Native, the end result can look like this:

{
  fontSize: 15
}

@jacobp100
Copy link
Contributor

I definitely get what you're trying to do! Maybe a better example of what I'm trying to say could be,

--body-size: 14px;
font: var(--body-size) "Helvetica";

If you removed the px in --body-size, as you proposed, you'd get font: 14 "Helvetica", which would not parse.

This won't just apply to font though. margin, padding etc. all expect units, so they'd crash too!

@kristerkari
Copy link
Contributor Author

kristerkari commented Jun 18, 2018

You are correct that any shorthand values would throw if you use them together with var(). But like I said earlier, css-to-react-native should not have to worry about parsing values with var().

As a workaround I can match the shorthand values in a similar way that css-to-react-native does and use a placeholder value (random number), e.g.

--body-size: 14px;
font: var(--body-size) "Helvetica";

↓ ↓ ↓ ↓ ↓ ↓

--body-size: 14px;
font: 53463023px "Helvetica";

and then just replace 53463023 in the result with the custom prop value 14 or if I want to do some runtime matching I could just replace 53463023 from the parsed value with var(--body-size).

↓ ↓ ↓ ↓ ↓ ↓

{
   "--body-size": 14
   "fontFamily": "Helvetica",
   "fontSize": 53463023,
   "fontStyle": "normal",
   "fontVariant": [],
   "fontWeight": "normal"
}

↓ ↓ ↓ ↓ ↓ ↓

{
   "--body-size": 14
   "fontFamily": "Helvetica",
   "fontSize": "var(--body-size)",
   "fontStyle": "normal",
   "fontVariant": [],
   "fontWeight": "normal"
}

Copy link
Contributor

@jacobp100 jacobp100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go for it 👍

@kristerkari
Copy link
Contributor Author

@jacobp100 Now that I'm thinking about this again, maybe it would be better to allow the short hand props to pass both CSS functions and length units through the parser.

I can use the workaround I mentioned, but if I would implement support for any other CSS function (e.g. calc), then my code would be full of boilerplate code to handle the workarounds.

So what if we whitelist the most common CSS functions and make the parser transform this:

--body-size: 14px;
font: var(--body-size) "Helvetica";

into this:

{
   "--body-size": 14
   "fontFamily": "Helvetica",
   "fontSize": "var(--body-size)",
   "fontStyle": "normal",
   "fontVariant": [],
   "fontWeight": "normal"
}

What do you think?

@jacobp100
Copy link
Contributor

That won't quite work, since CSS vars can contain multiple or complex values.

--font-config: 14px/18px;
font: var(--font-config) "Helvetica";

The expected value for this would be { fontSize: 14, lineHeight: 18, fontFamily: "Helvetica" }. But we have no way to work this out in this library.

@kristerkari
Copy link
Contributor Author

Oh I didn't think of that! I guess in that case the only way is to implement the logic in my library

@jacobp100
Copy link
Contributor

Might be best! The logic gets quite complicated, especially when variables reference other variables!

@kristerkari kristerkari merged commit a27ba6f into styled-components:master Jun 22, 2018
@kristerkari kristerkari deleted the bugfix/dont-use-camel-case-for-css-custom-properties branch June 22, 2018 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants